#! /bin/bash
##############################################################
##
## Name		:	muse
## Description	:	Managed Unix Script Execution
## Date		:	20/07/2012
## Args		:	
##
##############################################################

##############################################################
##
## Name		:	usage
## Author	:	Bradley Atkins
## Description	:	Display the usage
## Date		:	20/10/2012
## Args		:	
## Status	:	Reviewed 	[n]
##			Tested 		[n]
##			Released 	[n]
##############################################################
usage()
{
	printf "\n"
	printf "\t%s\n" "usage: ${0##*/} [-acdefhlstvx] file file ..."
	printf "\n"
	printf "\t%s\n" "${0##*/} -a|--archive [tag]		:Archive tagged results"
	printf "\t%s\n" "${0##*/} -c|--clear   <tag> 	:Clear all or tagged results"
	printf "\t%s\n" "${0##*/} -d|--delete		:Delete tag"
	printf "\t%s\n" "${0##*/} -e|--explain <job>		:Display metadata for the plugin or suite file" 
	printf "\t%s\n" "${0##*/} -f|--find [tag]		:Find tagged results"
	printf "\t%s\n" "${0##*/} -fc|--findc [tag]		:Find tagged control files"
	printf "\t%s\n" "${0##*/} -ft|--findt [tag]		:Find tagged tmp files"
	printf "\t%s\n" "${0##*/} -h|--help"
	printf "\t%s\n" "${0##*/} -l|--list [cmd line]	:Enumerate run order of scheduled tasks"
	printf "\t%s\n" "${0##*/} -lf			:List all muse common functons"
	printf "\t%s\n" "${0##*/} -lf %pattern		:List all muse common functons 'like' pattern"
	printf "\t%s\n" "${0##*/} -lp			:List all muse plugins"
	printf "\t%s\n" "${0##*/} -lp %pattern		:List all muse plugins 'like' pattern"
	printf "\t%s\n" "${0##*/} -ls			:List all muse suites"
	printf "\t%s\n" "${0##*/} -ls %pattern		:List all muse suites 'like' pattern"
	printf "\t%s\n" "${0##*/} -s|--show [name]		:Show current tag"
	printf "\t%s\n" "${0##*/} -t|--tag  [name]		:Set results tag"
	printf "\t%s\n" "${0##*/} -vf name			:View function 'name'"
	printf "\t%s\n" "${0##*/} -vp name			:View plugin 'name'"
	printf "\t%s\n" "${0##*/} -vs name			:View suite 'name'"
	printf "\t%s\n" "${0##*/} -vif name			:Edit function 'name'"
	printf "\t%s\n" "${0##*/} -vip name			:Edit plugin 'name'"
	printf "\t%s\n" "${0##*/} -vis name			:Edit suite 'name'"
	printf "\t%s\n" "${0##*/} -x|--exec n,n		:Execute steps n and n"
	printf "\t%s\n" "${0##*/} -x|--exec n-n		:Execute steps n to n"
	printf "\n"
}
##############################################################
##
## Name		:	die_local
## Author	:	Bradley Atkins
## Description	:	Fail before we manage to bootstrap muse
## Date		:	20/10/2012
## Args		:	
## Status	:	Reviewed 	[n]
##			Tested 		[n]
##			Released 	[n]
##############################################################
die_local()
{
	echo "$1"
	exit 1
}

# TODO Refactor this after writing the message handlers
Check_for_fatal_errors()
{
	local MSG_LIST TMP NAMES
	
	MSG_LIST=$(m_check_state "FATAL")
	
	if [[ -n ${MSG_LIST} ]]
	then
		for TMP in ${MSG_LIST}
		do
			NAMES="${NAMES} ${TMP##*/}"
		done

		MSG="Fatal Error/s Reported in (${NAMES})"
		m_log_msg "${MSG}"
		m_fail 1 "Error:Fatal Error/s - Exiting (muse)" 
	fi
}

#======================================
# Make sure all valid users can access 
#	our runtime files
#======================================
umask u=rwx,g=rwx,o=

#======================================
# Start
#======================================
[[ $# -eq 0 ]] && usage && exit 1
cd /tmp || die_local "cd to /tmp failed"

#======================================
# Derive location of muse code from the soft link
#======================================

export M_ROOT="$(X=$(ls -l /usr/local/bin/muse | awk '{print $NF}');X=${X%/*};echo ${X%/*})"

## Map our muse code
set -a
M_BIN="${M_ROOT}/bin"
M_DATA="${M_ROOT}/data"
M_DB="${M_ROOT}/db"
M_LIB="${M_ROOT}/lib"
M_SYSTEM="${M_ROOT}/system"
M_TEST="${M_ROOT}/test"
M_HOSTS="${M_DATA}/muse.hosts"
M_CONSTANTS="${M_LIB}/muse.constants"
M_ENVIRONMENT="${M_LIB}/muse.env"
M_FUNCS="${M_SYSTEM}/muse.funcs"
set +a

#======================================
# Load muse common functions and constants
#======================================
[[ -f "${M_FUNCS}" ]] || die_local "Failed to find muse.funcs (${M_FUNCS})"
source "${M_FUNCS}" || die_local "Failed to source file (${M_FUNCS})"
[[ -f "${M_CONSTANTS}" ]] || die_local "Failed to find muse constants (${M_CONSTANTS})"
source "${M_CONSTANTS}" || die_local "Failed to source constants file (${M_CONSTANTS})"
[[ -f "${M_ENVIRONMENT}" ]] || die_local "Failed to find muse environment (${M_ENVIRONMENT})"
source "${M_ENVIRONMENT}" || die_local "Failed to source environment file (${M_ENVIRONMENT})"

#======================================
# If we are being run via ssh then 
#          we're a slave
#======================================
if [[ -n ${SSH_CONNECTION} ]] 
then
	M_RUN_COUNTER="${P_RUN_COUNTER}"
	M_MASTER_HOST="${P_MASTER_HOST}"
	M_JOB_ID=${P_JOB_ID}
	M_RND=${P_RND}
	M_JOB_BG=N
	M_JOB_WAIT=N
	M_USR_TAG="${P_USR_TAG}"
	M_MSG_PIPE=${P_MSG_PIPE}

	if [[ ${M_MASTER_HOST} == $(hostname) ]]
	then
		M_SYS_TAG=".${P_SYS_TAG}"
	else
		M_SYS_TAG="${P_SYS_TAG}"
	fi
	M_MUSE_STATUS="slave"
else
	M_MUSE_STATUS="master"
fi

#======================================
# Set our environment variables
#======================================
m_set_runtime_env
	
#======================================
# Create our runtime directories and
# map file
#======================================
m_init 
m_map_muse

#======================================
# Process the args
#======================================
m_validate_cmd_line $@
[[ ${M_ACTION} == NORUN ]] && exit 0 ## No run so exit

#======================================
# We should now have our job list in
# M_RUN_LIST
#======================================
[[ -n ${M_RUN_LIST} ]] || m_fail 1 "Error:Empty run list (muse)" 

#======================================
# Print a header for the master stdout
#======================================
[[ ${M_MUSE_STATUS} == "master" ]] && m_print_master_header

for M_JOB_FILE in ${M_RUN_LIST}
do
	m_execute 
	if [[ ${M_MUSE_STATUS} == "master" ]]
	then
		m_get_msgs
		if [[ $? -eq 0 ]] ## We have unprocessed msgs
		then
			m_prioritise_msgs
			m_process_msg_queue
		fi
	fi
done

[[ ${M_MUSE_STATUS} == "master" ]] && m_print_master_footer

## TODO Test fatal and manual state thrown in last job

#======================================
# Cleanup
#======================================
m_post_run_tasks

#======================================
# Generic wait to clean up zombies etc
#======================================
wait

